/*
 *
 * Copyright (C) 2012 Walter Lütgenau
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */
package offset.nodes.client.editor.model;

import java.io.IOException;
import javax.swing.text.BadLocationException;
import javax.swing.text.Element;
import javax.swing.text.html.HTML;

/**
 *
 * @author Walter Luetgenau
 */
public class CharacterModel extends EditorModel {

    public CharacterModel(DocumentContext context) {
        super(context);
    }

    /**
     * Highlight the given range using the given inline element tag.
     * 
     * @param tag The inline element tag
     * @param range The range to substitute
     * 
     * @throws javax.swing.text.BadLocationException
     * @throws java.io.IOException
     * @throws java.lang.Exception
     */
    protected void highlightRange(String tag, Range range) throws BadLocationException, IOException, Exception {
        Element noImplied = getParagraphWithNoImpliedSiblings(getRealParagraph(range.getStartOffset()));
        Element e = getRealParagraph(range.getStartOffset());
        String html = substituteRange(e, buildSpan(tag, range), range.getStartOffset(), range.getEndOffset());

        if (noImplied != e) {
            setOuterHTML(noImplied, getStartTag(noImplied) + substituteElementByOuterHTMLGetParentInnerHTML(e, html) + getEndTag(noImplied));
            return;
        }

        setOuterHTML(e, html);
    }

    protected String buildSpan(String tag, Range range) throws BadLocationException {
        String html = null;
        if (tag != null)
            html = "<" + tag + ">" +
                    getDocument().getText(range.getStartOffset(), range.getEndOffset() - range.getStartOffset()) +
                    "</" + tag + ">";
        else
            html = getDocument().getText(range.getStartOffset(), range.getEndOffset() - range.getStartOffset());
        
        return html;
    }

    /**
     * Set the given range to bold.
     * 
     * @param range
     * @throws javax.swing.text.BadLocationException
     * @throws java.io.IOException
     * @throws java.lang.Exception
     */
    public void setBold(Range range) throws BadLocationException, IOException, Exception {
        highlightRange(HTML.Tag.B.toString(), range);
    }

    /**
     * Set the given range to italic.
     * 
     * @param range
     * @throws javax.swing.text.BadLocationException
     * @throws java.io.IOException
     * @throws java.lang.Exception
     */
    public void setItalic(Range range) throws BadLocationException, IOException, Exception {
        highlightRange(HTML.Tag.I.toString(), range);
    }

    /**
     * Set the given range to underline
     * 
     * @param range
     * @throws javax.swing.text.BadLocationException
     * @throws java.io.IOException
     * @throws java.lang.Exception
     */
    public void setUnderline(Range range) throws BadLocationException, IOException, Exception {
        highlightRange(HTML.Tag.U.toString(), range);
    }

    /**
     * Set the given range to "code".
     * 
     * @param range
     * @throws javax.swing.text.BadLocationException
     * @throws java.io.IOException
     * @throws java.lang.Exception
     */
    public void setCode(Range range) throws BadLocationException, IOException, Exception {
        highlightRange(HTML.Tag.CODE.toString(), range);
    }

    /**
     * Remove any inline element tags from the given range.
     * 
     * @param range
     * @throws javax.swing.text.BadLocationException
     * @throws java.io.IOException
     * @throws java.lang.Exception
     */
    public void setStandard(Range range) throws BadLocationException, IOException, Exception {
        highlightRange(null, range);
    }
}
